﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Marbles.Core.Handlers;
using Marbles.Core.Content.Sites;
using System.Web;
using Marbles.Core.Content.Pages;
using Marbles.Core.Content.Syndication;
using Marbles.Core.Content.SiteMap;

namespace Marbles.Core.Handlers
{
    public class AtomFeed : IHttpHandlerBase
    {
        public List<IFeedItem> Items
        {
            get { return _items; }
            set { _items = value; }
        }

        public static string ContentType { get { return "application/atom+xml"; } }

        public bool IsReusable
        {
            get { return false; }
        }


        private List<IFeedItem> _items = null;

        public AtomFeed()
            : base()
        {
            _items = new List<IFeedItem>();
        }

        public AtomFeed(List<IFeedItem> items)
            : base()
        {
            _items = items;
        }


        public void ProcessRequest(HttpContext context)
        {
            string PageName = "Default";
            if (Marbles.Core.Settings.SettingsManager.TrustLevel == AspNetHostingPermissionLevel.Medium)
            {
                if (context.Request.Params["id"] != null) { PageName = context.Request.Params["id"].Trim().ToLower(); }
            }
            else { PageName = (context.Items["Name"] == null ? "Default" : context.Items["Name"].ToString()); }
            
            SiteDefinition site = SiteDefinition.GetCurrent();
            PageDefinition page = new PageDefinition(site.SiteName, PageName);
            context.Response.ContentType = ContentType;

            WebSiteMap map = new WebSiteMap(page, true);
            GetFeedItems(map, _items);

            Render(context.Response, page, site, _items);
            context.Response.Flush();
            context.Response.End();
        }

        private void GetFeedItems(WebSiteMap map, List<IFeedItem> items)
        {
            foreach (WebSiteMapNode node in map)
            {
                FeedItem item = new FeedItem();
                item.Title = node.Title;
                item.Description = node.Description;
                item.PublishDate = node.PublishDate;
                item.Link = node.Url;
                items.Add(item);
                if (node.HasChildren) { GetFeedItems(map, items); }
            }
        }

        public void Render(HttpResponse writer, PageDefinition Page, SiteDefinition Web, List<IFeedItem> Items)
        {
            writer.Write("<?xml version=\"1.0\"?>");
            writer.Write("<feed xmlns=\"http://www.w3.org/2005/Atom\">");
            writer.Write("<title>" + HttpUtility.HtmlEncode(Web.Title) + "</title>");
            writer.Write("<link href=\"" + HttpUtility.HtmlEncode(Page.Link) + "\"/>");
            writer.Write("<updated>" + Page.PublishDate.ToString("r") + "</updated>");
            writer.Write("<author>");
            writer.Write("<name>" + HttpUtility.HtmlEncode(Page.ManagingEditor) + "</name>");
            writer.Write("</author>");

            foreach (IFeedItem item in Items)
            {
                writer.Write("<entry>");
                writer.Write("<id>" + item.GetHashCode().ToString() + "</id>");
                writer.Write("<title>" + HttpUtility.HtmlEncode(item.Title) + "</title>");
                writer.Write("<updated>" + item.PublishDate.ToString("r") + "</updated>");
                writer.Write("<author><name>" + HttpUtility.HtmlEncode(item.Author) + "</name></author>");
                writer.Write("<content>" + HttpUtility.HtmlEncode(item.Description) + "</content>");
                writer.Write("<link>" + HttpUtility.HtmlEncode(item.Link) + "</link>");
                writer.Write("<summary>" + HttpUtility.HtmlEncode(item.Description) + "</summary>");
                writer.Write("</entry>");
            }


            writer.Write("</feed>");
        }

        public string Verbs
        {
            get { return "GET"; }
        }

        public bool Validate
        {
            get { return false; }
        }

        public string Path
        {
            get { return "*.atom"; }
        }

        public string Name
        {
            get { return this.GetType().Name; }
        }
    }
}